import os
import sys
import time
import json
import socket
from threading import Thread

import traceback

import re

import log_manager
import shell

match_expression = "##[^\\\\]*"
'''
client_config = {
    "client" : [
        {
            "ip": "169.254.84.248",
            "port": 8000,
            "interval" : 1,
            "simulate_data" : "TestData/test_tx.txt",
            "match_expression" : "##[^\\\\]*"
        },
        {
            "ip": "169.254.84.248",
            "port": 12005,
            "interval" : 1.5,
            "simulate_data" : "TestData/test_tx.txt",
            "match_expression" : "##[^\\\\]*"
        },
        {
            "ip": "169.254.84.248",
            "port": 12006,
            "interval" : 2,
            "simulate_data" : "TestData/test_tx.txt",
            "match_expression" : "##[^\\\\]*"
        }
    ]
}
'''
'''
client_config = {
    "client" : [
        {
            "ip": "127.0.0.1",
            "port": 8000,
            "interval" : 1,
            "simulate_data" : "TestData/test_tx.txt",
            "match_expression" : "##[^\\\\]*"
        },
        {
            "ip": "127.0.0.1",
            "port": 12005,
            "interval" : 1.5,
            "simulate_data" : "TestData/test_tx.txt",
            "match_expression" : "##[^\\\\]*"
        },
        {
            "ip": "127.0.0.1",
            "port": 12006,
            "interval" : 2,
            "simulate_data" : "TestData/test_tx.txt",
            "match_expression" : "##[^\\\\]*"
        }
    ]
}
'''
client_config_test = {
    "client" : [
        {
            "ip": "127.0.0.1",
            "port": 8001,
            "interval" : 10,
            "simulate_data" : "TestData/test_tx.txt",
            "match_expression" : "##[^\\\\]*"
        }
    ]
}
client_config_debug = {
    "client" : [
        {
            "ip": "169.254.84.248",
            "port": 8000,
            "interval" : 1,
            "simulate_data" : "TestData/test_tx.txt",
            "match_expression" : "##[^\\\\]*"
        }
    ]
}
# client_config = client_config_debug
client_config = client_config_test
log_config = {
    "name" : "simulate",
    "level" : "DEBUG",
    "output-file" : [
        {
            "path": "log/simulate.log",
            "level": "DEBUG",
            "fmt": "%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s",
            "datefmt": None,
            "style": "%"
        }
    ],
    "terminal" : {
        "level": "DEBUG",
        "fmt": "(%(asctime)s)%(filename)s[line:%(lineno)d][%(levelname)s]: %(message)s",
        "datefmt": None,
        "style": "%",
        "level-fmt": {
            "DEBUG": {
                "prefix": "\u001B[36m",
                "suffix": "\u001B[0m"
            },
            "INFO": {
                "prefix": "\u001B[1;0m",
                "suffix": "\u001B[0m"
            },
            "WARNING": {
                "prefix": "\u001B[33m",
                "suffix": "\u001B[0m"
            },
            "ERROR": {
                "prefix": "\u001B[31m",
                "suffix": "\u001B[0m"
            },
            "CRITICAL": {
                "prefix": "\u001B[1;31m",
                "suffix": "\u001B[0m"
            }
        }
    }
}
class HJ212ClientSimulate:
    def __init__(self, config):
        self.addr = (config["ip"], config["port"])
        self.interval = config["interval"] * 10
        with open(config["simulate_data"], "r") as fd:
            pattern = re.compile(config["match_expression"])
            self.datalist = pattern.findall(fd.read())
            if not self.datalist:
                self.datalist = []
        self.exit_state = False
        self.tid = None
        # self.start()
    def start(self):
        self.exit_state = False
        self.tid = Thread(target=self.socket_send_thread, args=(self.datalist, ))
        self.tid.start()
    def stop(self):
        self.exit_state = True
        if self.tid:
            self.tid.join()
    def socket_send_thread(self, data_list):
        self.socket_send_loop(data_list)
    def socket_send_loop(self, data_list):
        client = socket.socket()
        if len(data_list) <= 0:
            log.error("data_list %d"%(len(data_list)))
            return
        try:
            client.connect(self.addr)
            index = 0
            while not self.exit_state:
                send_data = (data_list[index] + '\r\n').encode("utf-8")
                client.sendall(send_data)
                log.debug("\n" + str(send_data))
                for i in range(0, int(self.interval)):
                    if self.exit_state:
                        break
                    else:
                        time.sleep(0.1)
                index += 1
                if index >= len(data_list):
                    index = 0
        except Exception as e:
            log.error("%s:Exception-(%s)(%s)\n%s"%(str(self.addr), str(type(e)), str(e), traceback.format_exc()))
        finally:
            client.close()

class HJ212SimulateShell(shell.shell):
    def do_stop(self, arg):
        for client in client_list:
            client.stop()
    def do_start(self, arg):
        for client in client_list:
            client.start()

if __name__ == '__main__':
    log=log_manager.Logger(log_config)
    sh = HJ212SimulateShell(log=log)
    client_list = []
    for client in client_config["client"]:
        client_list.append(HJ212ClientSimulate(client))
    sh.cmdloop()

    for client in client_list:
        client.stop()
    print(log_config)














